/*
 * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.xw.sample.dashboardviewdemo.util;

/**
 * 渐变色计算
 */
public class ArgbEvaluator {
    private static final ArgbEvaluator mInstance = new ArgbEvaluator();

    /**
     * getInstance
     *
     * @return ArgbEvaluator
     */
    public static ArgbEvaluator getInstance() {
        return mInstance;
    }

    /**
     * evaluate
     *
     * @param fraction   fraction
     * @param startValue startValue
     * @param endValue   endValue
     * @return Object
     */
    public Object evaluate(float fraction, Object startValue, Object endValue) {
        int startInt = 0;
        if (startValue instanceof Integer) {
            startInt = (Integer) startValue;
        }
        float startA = ((startInt >> 24) & 0xff) / 255.0f;
        float startR = ((startInt >> 16) & 0xff) / 255.0f;
        float startG = ((startInt >> 8) & 0xff) / 255.0f;
        float startB = (startInt & 0xff) / 255.0f;
        int endInt = 0;
        if (endValue instanceof Integer) {
            endInt = (Integer) endValue;
        }
        float endA = ((endInt >> 24) & 0xff) / 255.0f;
        float endR = ((endInt >> 16) & 0xff) / 255.0f;
        float endG = ((endInt >> 8) & 0xff) / 255.0f;
        float endB = (endInt & 0xff) / 255.0f;

        // convert from sRGB to linear
        startR = (float) Math.pow(startR, 2.2);
        startG = (float) Math.pow(startG, 2.2);
        startB = (float) Math.pow(startB, 2.2);

        endR = (float) Math.pow(endR, 2.2);
        endG = (float) Math.pow(endG, 2.2);
        endB = (float) Math.pow(endB, 2.2);

        // compute the interpolated color in linear space
        float aStart = startA + fraction * (endA - startA);
        float rStart = startR + fraction * (endR - startR);
        float gStart = startG + fraction * (endG - startG);
        float bStart = startB + fraction * (endB - startB);

        // convert back to sRGB in the [0..255] range
        aStart = aStart * 255.0f;
        rStart = (float) Math.pow(rStart, 1.0 / 2.2) * 255.0f;
        gStart = (float) Math.pow(gStart, 1.0 / 2.2) * 255.0f;
        bStart = (float) Math.pow(bStart, 1.0 / 2.2) * 255.0f;
        return Math.round(aStart) << 24 | Math.round(rStart) << 16 | Math.round(gStart) << 8 | Math.round(bStart);
    }
}